package com.sample.service.impls;

import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sample.dto.GoodsDTO;
import com.sample.entity.Goods;
import com.sample.exception.StockLackException;
import com.sample.mapper.GoodsMapper;
import com.sample.service.GoodsService;
import com.swak.annotation.Tcc;
import com.swak.service.BaseService;
import com.swak.utils.Ints;

/**
 * 描述
 * 
 * @author Auto Generator
 * @date 2022-04-21T20:46:30.806130
 */
@DubboService
@Service("swakGoodsService")
public class GoodsServiceImpl extends BaseService<Goods, Long> implements GoodsService {

	@Autowired
	private GoodsMapper goodsMapper;

	@Tcc(confirm = "bookConfirm", cancel = "bookCancel")
	@Transactional
	@Override
	public GoodsDTO book(GoodsDTO goods) {

		/*
		 * 锁住当前用户
		 */
		Goods lockGoods = goodsMapper.lock(goods.getId());

		/*
		 * 校验金额
		 */
		Integer remainQuantity = Ints.subI(lockGoods.getQuantity(), goods.getQuantity());
		if (remainQuantity == null || remainQuantity < 0) {
			throw new StockLackException();
		}

		/*
		 * 修改剩余的金额和冻结的金额
		 */
		Goods.of().setQuantity(remainQuantity).setFreeze(Ints.addI(lockGoods.getFreeze(), goods.getQuantity()))
				.setId(lockGoods.getId()).updateSelective();

		/*
		 * 返回最新的数据
		 */
		return GoodsDTO.convert(goodsMapper.get(goods.getId()));
	}

	@Transactional
	public void bookConfirm(GoodsDTO goods) {
		/*
		 * 锁住当前用户
		 */
		Goods lockGoods = goodsMapper.lock(goods.getId());

		/*
		 * 扣除冻结的库存
		 */
		Goods.of().setFreeze(Ints.subI(lockGoods.getFreeze(), goods.getQuantity())).setId(goods.getId())
				.updateSelective();
	}

	@Transactional
	public void bookCancel(GoodsDTO goods) {

		/*
		 * 锁住当前用户
		 */
		Goods lockGoods = goodsMapper.lock(goods.getId());

		/*
		 * 扣除冻结的金额
		 */
		Goods.of().setFreeze(Ints.subI(lockGoods.getFreeze(), goods.getQuantity()))
				.setQuantity(Ints.addI(lockGoods.getQuantity(), goods.getQuantity())).setId(goods.getId())
				.updateSelective();
	}
}
